perm filename PUPBGF.FAI[S,HE] blob
sn#721899 filedate 1983-08-03 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 TITLE PUPFAI - Subroutines for using PUP from SAIL
C00012 ENDMK
C⊗;
TITLE PUPFAI - Subroutines for using PUP from SAIL
ENTRY PUPINIT,PUPOUT,PUPFLUSH,PUPIN,PUPFINI,PUPSTAT,PUPOBLK
;EXTERNAL INTEGER PROCEDURE PUPINIT(INTEGER CHAN,HOST,SOCKET; REFERENCE INTEGER
; NWORDS);
; PUPINIT opens a full-duplex BSP connection using channel CHAN
; (you should get CHAN using GETCHAN). Take HOST and SOCKET
; from a call to NAMELOOKUP, for example. NWORDS will tell you the
; maximum number of 16-bit words to put in a buffer.
;******** NOTICE that PUPOUT and PUPFLUSH are lower level than usual
;EXTERNAL INTEGER PROCEDURE PUPOUT(INTEGER WORD);
; PUPOUT puts one word in the buffer. It doesn't check to make sure
; you aren't putting in too many.
;EXTERNAL INTEGER PROCEDURE PUPFLUSH;
; PUPFLUSH outputs any pending output to the connection.
;EXTERNAL INTEGER PROCEDURE PUPOBLK(REFERENCE INTEGER BUF; INTEGER LENGTH);
; PUPOBLK outputs a whole buffer with LENGTH 16-bit words starting at BUF.
; Each word in the buffer has two 16-bit words in it, packed into the
; left (the buffer is just transferred into a system buffer). Note
; that because of the way Whitney works, one 16-bit word goes into
; the buffer with the least signficant byte FIRST.
;EXTERNAL INTEGER PROCEDURE PUPIN(REFERENCE INTEGER WORD);
; PUPIN gets one word from the connection.
;EXTERNAL INTEGER PROCEDURE PUPFINI;
; PUPFINI closes the connection.
;EXTERNAL INTEGER PROCEDURE PUPSTAT;
; PUPSTAT returns the status word from the last MTAPE operation on
; the connection [for more thorough error recovery].
; All procedures return a value indicating the outcome of the operation:
; 0 = success
; 1 = illegal channel number
; 2 = OPEN failed on device PUP
; 3 = MTAPE to establish connection failed
; 4 = OUT failed while outputting buffer
; 5 = IN failed while reading buffer
; 6 = packet had an odd number of bytes in it on input
; 7 = buffer in block-mode output was too long to fit in buffer
;I don't believe this one
OPDEF ADJBP [IBP]
;AC defs
P←←17
;Defs for PUP MTAPE
MFUNC←←0
MSTAT←←1
MLSOCK←←2
MWAIT←←3
MBYTE←←4
MFSOCK←←5
MFHOST←←6
;Data area
RETAD: BLOCK 1 ; Return address
WRDAD: BLOCK 1 ; Address for no. of words in buffer, or word to return
MTPBLK: BLOCK 7 ; block for PUP MTAPE functions
CHANWD: BLOCK 1 ; channel in correct place for UUOs
OPNBLK: 0 ; block for PUP OPEN function
SIXBIT/PUP/
OBUFH,,IBUFH
OBUFH: BLOCK 3 ↔ IBUFH: BLOCK 3 ;buffer headers...don't separate these
PUPINIT: POP P,RETAD
POP P,WRDAD
POP P,MTPBLK+MFSOCK
POP P,MTPBLK+MFHOST
; Now get channel and set it up for future UUOs
MOVEI 1,1 ; Illegal channel
POP P,2
CAILE 2,17
JRST @RETAD ; Illegal channel error
LSH 2,=18+5
MOVEM 2,CHANWD
; Establish connection with foreign host
; zero buffer headers
SETZM OBUFH
MOVE 2,[OBUFH,,OBUFH+1]
BLT 2,IBUFH+2
; open device PUP
MOVEI 1,2 ; OPEN failed
MOVE 2,[OPEN 0,OPNBLK]
IOR 2,CHANWD
XCT 2
JRST @RETAD ; OPEN failed error
; set byte size to 8
MOVEI 2,=8
DPB 2,[POINT 6,OBUFH+1,11]
DPB 2,[POINT 6,IBUFH+1,11]
; use MTAPE to establish connection
SETZM MTPBLK+MFUNC ; function = establish connection
SETZM MTPBLK+MSTAT ; status = no error yet
SETOM MTPBLK+MLSOCK ; local socket = generate one (-1)
SETOM MTPBLK+MWAIT ; wait for function completion
MOVEM 2,MTPBLK+MBYTE ; byte size = 8
MOVE 2,[MTAPE 0,MTPBLK]
IOR 2,CHANWD
XCT 2
MOVEI 1,3 ; MTAPE failed
MOVE 2,MTPBLK+MSTAT
ANDI 2,77
JUMPN 2,@RETAD ; MTAPE failed error
; set up buffers with OUT UUO.
MOVEI 1,4 ; OUT failed
MOVE 2,[OUT 0,]
IOR 2,CHANWD
XCT 2
JRST .+2
JRST @RETAD ; OUT UUO failed error
; set the number of 16-bit words in the buffer
MOVE 2,OBUFH+2
LSH 2,-1 ; bytes to 16-bit words
MOVEM 2,@WRDAD
; successful operation
MOVEI 1,0 ; success
JRST @RETAD
PUPSTAT: MOVE 1,MTPBLK+MSTAT
POPJ P,
PUPOUT: POP P,RETAD
POP P,2
MOVE 3,2
LSH 3,-=8
IDPB 2,OBUFH+1 ; Deposit low-order byte
IDPB 3,OBUFH+1 ; Deposit high-order byte
SOS OBUFH+2 ; Update count just in case
SOS OBUFH+2
MOVEI 1,0 ; and give success return
JRST @RETAD
PUPFLUSH: MOVE 2,[OUT 0,]
MOVEI 1,0
IOR 2,CHANWD
XCT 2
POPJ P, ; success return
MOVEI 1,4 ; OUT failed
POPJ P, ; OUT failed error
PUPOBLK:POP P,RETAD
POP P,3 ; get length in 16-bit words
POP P,2 ; and address of user buf
MOVEI 1,7 ; buffer too long
MOVE 4,3 ; get length in 8-bit bytes
LSH 4,1
ADDI 3,1 ; get length in 36-bit words (rounded up)
LSH 3,-1
CAMLE 4,OBUFH+2
JRST @RETAD ; buffer too long error
MOVE 5,OBUFH+2 ; fix length in system buf header
SUB 5,4
MOVEM 5,OBUFH+2
IBP OBUFH+1 ; move byte pointer to first byte in system buf
HRL 5,2 ; set up BLT pointer:
HRR 5,OBUFH+1 ; 5 = user buf start,,system buf start
HRR 6,OBUFH+1
ADDI 6,-1(3) ; 6 = system buf end
IOR 6,[BLT 5,0] ; 6 = BLT instruction
XCT 6
SUBI 4,1 ; now fix up the byte pointer in system buf
ADJBP 4,OBUFH+1
MOVEM 4,OBUFH+1
MOVE 4,[OUT 0,] ; do OUT instruction to output buffer
MOVEI 1,0 ; success return
IOR 4,CHANWD
XCT 4
JRST @RETAD
MOVEI 1,4 ; OUT failed
JRST @RETAD ; OUT failed error
PUPIN: POP P,RETAD
POP P,WRDAD
; try to get one word from buffer
PUPI2: MOVEI 1,6 ; odd no. of bytes
SOSGE IBUFH+2
JRST GETBUF
SOSGE IBUFH+2
JRST @RETAD ; odd bytes error
ILDB 3,IBUFH+1 ; and low-order byte
ILDB 2,IBUFH+1 ; get high-order byte
LSH 2,=8 ; assemble word
IOR 2,3
MOVEM 2,@WRDAD ; store it
MOVEI 1,0 ; success return
JRST @RETAD
; none left in buffer - read a buffer
GETBUF: MOVE 2,[IN 0,]
IOR 2,CHANWD
XCT 2
JRST PUPI2
MOVEI 1,5 ; IN failed
JRST @RETAD ; IN failed error
PUPFINI: MOVE 2,[CLOSE 0,]
IOR 2,CHANWD
XCT 2
; do the RELEASE from SAIL now
; MOVE 2,[RELEAS 0,]
; IOR 2,CHANWD
; XCT 2
MOVEI 1,0 ; success return
POPJ P,
END